﻿using System;
using System.Diagnostics.Contracts;

namespace NColony.Dependencies.Contracts
{
    /// <summary>
    /// Contract for <see cref="IDependencyManager"/>.
    /// </summary>
    [ContractClassFor(typeof(IDependencyManager))]
    public abstract class IDependencyManagerContract : IDependencyManager
    {
        /// <summary>
        /// Resolves the dependencies.
        /// </summary>
        /// <param name="objectsWithDependencies">The objects with dependencies.</param>
        public void ResolveDependencies(params object[] objectsWithDependencies)
        {
            Contract.Requires(objectsWithDependencies.Length > 0, "objectsWithDependencies must contain at least one object");
        }

        /// <summary>
        /// Creates a lazy instance.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <returns>A lazy instance.</returns>
        public Lazy<T> CreateLazyInstance<T>()
        {
            Contract.Ensures(Contract.Result<Lazy<T>>() != null, "Return value will never be null");

            return default(Lazy<T>);
        }

        /// <summary>
        /// Creates the lazy instance.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <param name="dependencyLookupKey">The dependency lookup key.</param>
        /// <returns>A lazy instance.</returns>
        public Lazy<T> CreateLazyInstance<T>(string dependencyLookupKey)
        {
            Contract.Requires(!String.IsNullOrEmpty(dependencyLookupKey), "dependencyLookupKey cannot be null or empty");

            Contract.Ensures(Contract.Result<Lazy<T>>() != null, "Return value will never be null");

            return default(Lazy<T>);
        }

        /// <summary>
        /// Creates the instance or default.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <returns>An instance if found, otherwise null.</returns>
        public T CreateInstanceOrDefault<T>()
        {
            return default(T);
        }

        /// <summary>
        /// Creates the instance or default.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <param name="dependencyLookupKey">The dependency lookup key.</param>
        /// <returns>An instance if found, otherwise null.</returns>
        public T CreateInstanceOrDefault<T>(string dependencyLookupKey)
        {
            Contract.Requires(!String.IsNullOrEmpty(dependencyLookupKey), "dependencyLookupKey cannot be null or empty");

            return default(T);
        }

        /// <summary>
        /// Creates the instance.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <returns>
        /// An instance if found, otherwise throws an Exception.
        /// </returns>
        public T CreateInstance<T>()
        {
            Contract.Ensures(Contract.Result<T>() != null, "Return value will never be null");

            return default(T);
        }

        /// <summary>
        /// Creates the instance.
        /// </summary>
        /// <typeparam name="T">The type of instance to create.</typeparam>
        /// <param name="dependencyLookupKey">The dependency lookup key.</param>
        /// <returns>
        /// An instance if found, otherwise throws an Exception.
        /// </returns>
        public T CreateInstance<T>(string dependencyLookupKey)
        {
            Contract.Requires(!String.IsNullOrEmpty(dependencyLookupKey), "dependencyLookupKey cannot be null or empty");

            Contract.Ensures(Contract.Result<T>() != null, "Return value will never be null");

            return default(T);
        }
    }
}
